package com.maodou.core.datastore.db

import com.maodou.core.datastore.db.dao.UserCacheDao
import com.maodou.core.datastore.db.table.UserCacheEntry
import com.maodou.core.manager.GlobalStateManager
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types

/**
 * 用户感知的列表缓存工具
 * 支持多用户数据隔离，每个用户的缓存数据独立存储
 */
class UserAwareListCacheStore(
    val dao: UserCacheDao,
    val moshi: Moshi,
    val globalStateManager: GlobalStateManager
) {
    
    /**
     * 获取当前登录用户ID
     * @throws IllegalStateException 如果用户未登录
     */
    fun getCurrentUserId(): String {
        return globalStateManager.getCurrentUserId() 
            ?: throw IllegalStateException("User not logged in, cannot access user cache")
    }
    
    /**
     * 存储列表数据到当前用户的缓存
     */
    suspend inline fun <reified T> putList(
        key: String,
        value: List<T>,
        ttlSeconds: Long? = null,
    ) {
        val userId = getCurrentUserId()
        val type = Types.newParameterizedType(List::class.java, T::class.java)
        val adapter = moshi.adapter<List<T>>(type)
        val json = adapter.toJson(value)
        dao.upsert(
            UserCacheEntry(
            userId = userId,
            key = key, 
            json = json, 
            updatedAt = System.currentTimeMillis(), 
            ttlSeconds = ttlSeconds
        )
        )
    }
    
    /**
     * 从当前用户的缓存中获取列表数据
     */
    suspend inline fun <reified T> getList(
        key: String,
        acceptExpired: Boolean = true,
    ): List<T>? {
        val userId = getCurrentUserId()
        val entry = dao.get(userId, key) ?: return null
        
        // 检查是否过期
        if (!acceptExpired && entry.ttlSeconds != null) {
            val expired = entry.updatedAt + entry.ttlSeconds * 1000 < System.currentTimeMillis()
            if (expired) return null
        }
        
        val type = Types.newParameterizedType(List::class.java, T::class.java)
        val adapter = moshi.adapter<List<T>>(type)
        return runCatching { adapter.fromJson(entry.json) }.getOrNull()
    }
    
    /**
     * 删除当前用户的特定缓存
     */
    suspend fun delete(key: String) {
        val userId = getCurrentUserId()
        dao.delete(userId, key)
    }
    
    /**
     * 清除当前用户的所有缓存数据
     */
    suspend fun clearCurrentUserData() {
        val userId = getCurrentUserId()
        dao.clearUserData(userId)
    }
    
    /**
     * 清除当前用户的过期缓存
     */
    suspend fun clearCurrentUserExpired(nowMs: Long = System.currentTimeMillis()) {
        val userId = getCurrentUserId()
        dao.clearUserExpired(userId, nowMs)
    }
    
    /**
     * 获取当前用户的缓存数量
     */
    suspend fun getCurrentUserCacheCount(): Int {
        val userId = getCurrentUserId()
        return dao.countByUser(userId)
    }
    
    /**
     * 根据前缀获取当前用户的缓存列表
     */
    suspend fun getByPrefix(prefix: String): List<UserCacheEntry> {
        val userId = getCurrentUserId()
        return dao.getByPrefix(userId, prefix)
    }
    
    // ==================== 管理员功能 ====================
    
    /**
     * 清除指定用户的所有缓存数据（管理员功能）
     */
    suspend fun clearUserData(userId: String) {
        dao.clearUserData(userId)
    }
    
    /**
     * 清除所有用户的缓存数据（管理员功能）
     */
    suspend fun clearAll() {
        dao.clearAll()
    }
    
    /**
     * 清除所有过期缓存（管理员功能）
     */
    suspend fun clearAllExpired(nowMs: Long = System.currentTimeMillis()) {
        dao.clearExpired(nowMs)
    }
    
    /**
     * 获取所有用户ID列表（管理员功能）
     */
    suspend fun getAllUserIds(): List<String> {
        return dao.getAllUserIds()
    }
}